using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Box2D.XNA;


namespace WindowsPhoneGame1
{

    public class CollisionDetector : IContactListener
    {
        protected List<Body> buttonList = new List<Body>();
        protected List<Body> uplList = new List<Body>();
        protected List<Body> leftlList = new List<Body>();
        protected List<Body> rightList = new List<Body>();
        protected List<Body> contactBodylList = new List<Body>();
        protected Body _body;

        public CollisionDetector(Body body)
        {
            this._body = body;
            
        }

        private Body GetContactedBody(Contact contact)
        {
            if (contact.GetFixtureA().GetBody() == this._body)
            {
                return contact.GetFixtureB().GetBody();
            }
            else if (contact.GetFixtureB().GetBody() == this._body)
            {
                return contact.GetFixtureA().GetBody();
            }
            return null;
        }

        private Vector2 GetContactAngle(Contact contact)
        {
            Vector2 angVector2 = new Vector2();
            
            if (contact.GetFixtureA().GetBody() == this._body)
            {
                //Gdx.app.log("this.body=", "A");
                WorldManifold w;
                contact.GetWorldManifold(out w);
                angVector2 = w._normal;
            }
            else
            {
                WorldManifold w;
                contact.GetWorldManifold(out w);
                angVector2 = w._normal;
                angVector2 *= -1;
                // angVector2
                //return contact.getFixtureA().getBody();
            }
            return angVector2;
        }

        private void checkList(List<Body> list)
        {
            foreach (Body b in list)
            {
                if (!contactBodylList.Contains(b))
                    foreach (Body body in list)
                        list.Remove(body);
            }
        }

        public void BeginContact(Contact contact)
        {
            float normal = (float)Math.Atan2(GetContactAngle(contact).Y, GetContactAngle(contact).X);
            Body contactBody = GetContactedBody(contact);
            Object userData = contactBody.GetUserData();
            if (userData != null)
                if (true)
                {

                    if (normal > 45 && normal < 135)//button
                        if (!buttonList.Contains(contactBody))
                            buttonList.Add(contactBody);

                    if (normal > 135 && normal < 215)//right
                        if (!rightList.Contains(contactBody))
                            rightList.Add(contactBody);

                    if (normal > 225 && normal < 315)//up
                        if (!uplList.Contains(contactBody))
                            uplList.Add(contactBody);

                    if (normal > 315 || normal < 45)//left
                        if (!leftlList.Contains(contactBody))
                            leftlList.Add(contactBody);

                }
        }

        public void pollingContact()
        {

            contactBodylList.Clear();

            Contact contact = _body.GetWorld().GetContactList();
            while (contact != null)
            {
                Body b = GetContactedBody(contact);
                if (b != null)
                {
                    if (!contactBodylList.Contains(b))
                        contactBodylList.Add(b);

                }
                contact = contact.GetNext();
            }

            checkList(buttonList);
            checkList(leftlList);
            checkList(rightList);
            checkList(uplList);


        }

        public void EndContact(Contact contact)
        {
            Body contactBody = GetContactedBody(contact);
            //Gdx.app.log("this.body=", "B");

            contactBodylList.Remove(contactBody);

            while (buttonList.Contains(contactBody))
                buttonList.Remove(contactBody);

            for (int i = 0; i < rightList.Count(); i++)
                rightList.Remove(contactBody);

            for (int i = 0; i < uplList.Count(); i++)
                uplList.Remove(contactBody);

            for (int i = 0; i < leftlList.Count(); i++)
                leftlList.Remove(contactBody);

        }

        public void PreSolve(Contact contact, ref Manifold oldManifold)
        {
            //throw new NotImplementedException();
        }

        public void PostSolve(Contact contact, ref ContactImpulse impulse)
        {
            //throw new NotImplementedException();
        }
    }
}
